package com.yl.message.service.impl.sendNoticeImpl

import com.alibaba.fastjson.JSONObject
import com.tencentcloudapi.common.Credential
import com.tencentcloudapi.common.profile.ClientProfile
import com.tencentcloudapi.common.profile.HttpProfile
import com.tencentcloudapi.sms.v20210111.SmsClient
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse

import com.yl.common.ErrorCode
import com.yl.common.control.ResponseBody
import com.yl.common.control.returnError
import com.yl.common.control.returnSuccess
import com.yl.message.common.MessageType
import com.yl.message.common.annotation.MsgTypeHandler
import com.yl.message.service.MessageService
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service


@Service
@MsgTypeHandler(MessageType.TENCENT_SMS)
class TencentSmsServiceImpl():MessageService {

	companion object {
		private val log = LoggerFactory.getLogger(SmsMessageServiceImpl::class.java)!!
	}

	override fun send(config: JSONObject, userId: Long, msgBody: JSONObject): ResponseBody {
		val phone = config.getString("mobilePhone") ?: return returnError(
			ErrorCode.SEND_MESSAGE_ERROR,"没有电话号码"
		)
		val templateId = config.getString("templateId")?: return returnError(
			ErrorCode.SEND_MESSAGE_ERROR,"请输入短信发送模板"
		)
		val content = msgBody.getString("message")?:return returnError(
			ErrorCode.SEND_MESSAGE_ERROR,"请输入短信发送内容"
		)
		val appId = config.getString("appId")?:return returnError(
			ErrorCode.SEND_MESSAGE_ERROR,"未设置短信发送appId"
		)
		return send(appId,phone,templateId,content)
	}

	private fun send(appId:String,phone:String,templateId:String,content:String):ResponseBody{
		log.info("腾讯sms短信发送 appId:$appId,phone:$phone,templateId:$templateId,content:$content")
		try {
			/* 必要步骤：
             * 实例化一个认证对象，入参需要传入腾讯云账户密钥对secretId，secretKey。
             * 这里采用的是从环境变量读取的方式，需要在环境变量中先设置这两个值。
             * 你也可以直接在代码中写死密钥对，但是小心不要将代码复制、上传或者分享给他人，
             * 以免泄露密钥对危及你的财产安全。
             * CAM密匙查询: https://console.cloud.tencent.com/cam/capi*/

			/* 必要步骤：
             * 实例化一个认证对象，入参需要传入腾讯云账户密钥对secretId，secretKey。
             * 这里采用的是从环境变量读取的方式，需要在环境变量中先设置这两个值。
             * 你也可以直接在代码中写死密钥对，但是小心不要将代码复制、上传或者分享给他人，
             * 以免泄露密钥对危及你的财产安全。
             * CAM密匙查询: https://console.cloud.tencent.com/cam/capi*/
			val cred = Credential("AKIDRhhRt4yEExOZU9X9VbQyGH0SfbGekbAS", "2oKZWDdmdEZdQvA8pFPIuFJ6crpXy81e")
			// 实例化一个http选项，可选，没有特殊需求可以跳过
			// 实例化一个http选项，可选，没有特殊需求可以跳过
			val httpProfile = HttpProfile()
			/* 设置代理
			* httpProfile.setProxyHost("真实代理ip");
			* httpProfile.setProxyPort(真实代理端口);
			* SDK默认使用POST方法。
             * 如果你一定要使用GET方法，可以在这里设置。GET方法无法处理一些较大的请求 */
			/* 设置代理
			* httpProfile.setProxyHost("真实代理ip");
			* httpProfile.setProxyPort(真实代理端口);
			* SDK默认使用POST方法。
             * 如果你一定要使用GET方法，可以在这里设置。GET方法无法处理一些较大的请求 */
			httpProfile.reqMethod = "POST"
			/* SDK有默认的超时时间，非必要请不要进行调整
             * 如有需要请在代码中查阅以获取最新的默认值 */
			/* SDK有默认的超时时间，非必要请不要进行调整
             * 如有需要请在代码中查阅以获取最新的默认值 */httpProfile.connTimeout = 60
			/* SDK会自动指定域名。通常是不需要特地指定域名的，但是如果你访问的是金融区的服务
             * 则必须手动指定域名，例如sms的上海金融区域名： sms.ap-shanghai-fsi.tencentcloudapi.com */
			/* SDK会自动指定域名。通常是不需要特地指定域名的，但是如果你访问的是金融区的服务
             * 则必须手动指定域名，例如sms的上海金融区域名： sms.ap-shanghai-fsi.tencentcloudapi.com */
			httpProfile.endpoint =
				"sms.tencentcloudapi.com"

			/* 非必要步骤:
             * 实例化一个客户端配置对象，可以指定超时时间等配置 */

			/* 非必要步骤:
             * 实例化一个客户端配置对象，可以指定超时时间等配置 */
			val clientProfile = ClientProfile()
			/* SDK默认用TC3-HMAC-SHA256进行签名
             * 非必要请不要修改这个字段 */
			/* SDK默认用TC3-HMAC-SHA256进行签名
             * 非必要请不要修改这个字段 */
			clientProfile.signMethod = "HmacSHA256"
			clientProfile.httpProfile = httpProfile
			/* 实例化要请求产品(以sms为例)的client对象
             * 第二个参数是地域信息，可以直接填写字符串ap-guangzhou，或者引用预设的常量 */
			/* 实例化要请求产品(以sms为例)的client对象
             * 第二个参数是地域信息，可以直接填写字符串ap-guangzhou，或者引用预设的常量 */
			val client = SmsClient(cred, "ap-guangzhou", clientProfile)
			/* 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
             * 你可以直接查询SDK源码确定接口有哪些属性可以设置
             * 属性可能是基本类型，也可能引用了另一个数据结构
             * 推荐使用IDE进行开发，可以方便的跳转查阅各个接口和数据结构的文档说明 */
			/* 实例化一个请求对象，根据调用的接口和实际情况，可以进一步设置请求参数
             * 你可以直接查询SDK源码确定接口有哪些属性可以设置
             * 属性可能是基本类型，也可能引用了另一个数据结构
             * 推荐使用IDE进行开发，可以方便的跳转查阅各个接口和数据结构的文档说明 */
			val req = SendSmsRequest()

			/* 填充请求参数,这里request对象的成员变量即对应接口的入参
             * 你可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义
             * 基本类型的设置:
             * 帮助链接：
             * 短信控制台: https://console.cloud.tencent.com/smsv2
             * sms helper: https://cloud.tencent.com/document/product/382/3773 */

			/* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId，示例如1400006666 */

			/* 填充请求参数,这里request对象的成员变量即对应接口的入参
             * 你可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义
             * 基本类型的设置:
             * 帮助链接：
             * 短信控制台: https://console.cloud.tencent.com/smsv2
             * sms helper: https://cloud.tencent.com/document/product/382/3773 */

			/* 短信应用ID: 短信SdkAppId在 [短信控制台] 添加应用后生成的实际SdkAppId，示例如1400006666 */
			req.smsSdkAppId = appId


			/* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名，签名信息可登录 [短信控制台] 查看 */

			/* 短信签名内容: 使用 UTF-8 编码，必须填写已审核通过的签名，签名信息可登录 [短信控制台] 查看 */
			val signName = "江西纵扬科技有限公司"
			req.signName = signName

			/* 国际/港澳台短信 SenderId: 国内短信填空，默认未开通，如需开通请联系 [sms helper] */

			/* 国际/港澳台短信 SenderId: 国内短信填空，默认未开通，如需开通请联系 [sms helper] */
			val senderid = ""
			req.senderId = senderid

			/* 用户的 session 内容: 可以携带用户侧 ID 等上下文信息，server 会原样返回 */

			/* 用户的 session 内容: 可以携带用户侧 ID 等上下文信息，server 会原样返回 */
			val sessionContext = ""
			req.sessionContext = sessionContext

			/* 短信号码扩展号: 默认未开通，如需开通请联系 [sms helper] */

			/* 短信号码扩展号: 默认未开通，如需开通请联系 [sms helper] */
			val extendCode = ""
			req.extendCode = extendCode

			/* 模板 ID: 必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看 */


			/* 模板 ID: 必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看 */
			req.templateId = templateId

			/* 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
             * 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号 */

			/* 下发手机号码，采用 E.164 标准，+[国家或地区码][手机号]
             * 示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号 */
			val phoneNumberSet = arrayOf(
				"+86$phone"
			)
			req.phoneNumberSet = phoneNumberSet

			/* 模板参数: 若无模板参数，则设置为空 */

			/* 模板参数: 若无模板参数，则设置为空 */
			val code: String = content
			val templateParamSet = arrayOf(code)
			req.templateParamSet = templateParamSet

			/* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
             * 返回的 res 是一个 SendSmsResponse 类的实例，与请求对象对应 */

			/* 通过 client 对象调用 SendSms 方法发起请求。注意请求方法名与请求对象是对应的
             * 返回的 res 是一个 SendSmsResponse 类的实例，与请求对象对应 */
			val res: SendSmsResponse = client.SendSms(req)
			// 输出json格式的字符串回包
			// 输出json格式的字符串回包
			println()
			log.info("输出json格式的字符串回报：{}", SendSmsResponse.toJsonString(res))

		}catch (e:Exception){
			e.printStackTrace()
			return returnError(ErrorCode.SEND_MESSAGE_ERROR)
		}
		return returnSuccess()
	}
}
